﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FgoDataCrawler.Crawler;
using FgoDataCrawler.Entity;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;

namespace FgoDataCrawler
{
    public class FgowikiDataExporter
    {
        public FgowikiCrawler Crawler { get; set; }
        private IWorkbook WorkingWorkbook { get; set; }

        public IDictionary<int, ServantInfo> ServantList { get; set; }
        public IDictionary<int, ServantErrata> ErrataTable { get; set; }  // 勘误表

        public FgowikiDataExporter()
        {
            Crawler = new FgowikiCrawler();
        }

        public void ExportAll(string path)
        {
            WorkingWorkbook = new XSSFWorkbook();

            ExportServants();

            // 保存关闭
            Stream stream = new FileStream(path, FileMode.Create);
            WorkingWorkbook.Write(stream);
            stream.Close();
            WorkingWorkbook.Close();
        }
        
        public void LoadErrata(string path)
        {
            FileStream sf = new FileStream(path, FileMode.Open);
            IWorkbook workbook = new XSSFWorkbook(sf);
            ISheet sheet = workbook.GetSheet("Servants");
            ErrataTable = new Dictionary<int, ServantErrata>();
            int rowNo = 1;
            while (true)
            {
                IRow row = sheet.GetRow(rowNo);
                if (row == null) break;
                ICell id = row.GetCell(0);
                ICell name = row.GetCell(1);
                ICell appmediaId = row.GetCell(2);
                ICell avatar = row.GetCell(3);

                ServantErrata errata = new ServantErrata();
                errata.Id = (int)id.NumericCellValue;
                errata.Name = (name != null) ? name.StringCellValue : null;
                errata.AppMediaId = (int)appmediaId.NumericCellValue;
                errata.Avatar = avatar.StringCellValue;

                ErrataTable[errata.Id] = errata;
                rowNo++;
            }
        }

        public bool ExportServants()
        {
            IList<ServantInfo> servants = Crawler.FetchServants();

            ISheet sheet = WorkingWorkbook.CreateSheet("Servants");

            // 创建前两行（列名与类型）
            IList<KeyValuePair<string, string>> columns = new List<KeyValuePair<string, string>>();
            columns.Add(new KeyValuePair<string, string>("id", "int"));
            columns.Add(new KeyValuePair<string, string>("name_jp", "string"));
            columns.Add(new KeyValuePair<string, string>("name_cn", "string"));
            columns.Add(new KeyValuePair<string, string>("name_en", "string"));
            columns.Add(new KeyValuePair<string, string>("class", "string"));
            columns.Add(new KeyValuePair<string, string>("rarity", "int"));
            columns.Add(new KeyValuePair<string, string>("cost", "int"));
            columns.Add(new KeyValuePair<string, string>("buster_card", "int"));
            columns.Add(new KeyValuePair<string, string>("arts_card", "int"));
            columns.Add(new KeyValuePair<string, string>("quick_card", "int"));
            columns.Add(new KeyValuePair<string, string>("buster_hits", "int"));
            columns.Add(new KeyValuePair<string, string>("arts_hits", "int"));
            columns.Add(new KeyValuePair<string, string>("quick_hits", "int"));
            columns.Add(new KeyValuePair<string, string>("ex_hits", "int"));
            columns.Add(new KeyValuePair<string, string>("np_charge_atk", "double"));
            columns.Add(new KeyValuePair<string, string>("np_charge_def", "double"));
            columns.Add(new KeyValuePair<string, string>("death_rate", "double"));
            columns.Add(new KeyValuePair<string, string>("star_abs", "int"));
            columns.Add(new KeyValuePair<string, string>("star_gen", "double"));
            columns.Add(new KeyValuePair<string, string>("attribute", "string"));
            columns.Add(new KeyValuePair<string, string>("alignments", "string"));
            columns.Add(new KeyValuePair<string, string>("gender", "int"));
            columns.Add(new KeyValuePair<string, string>("appmedia_id", "int"));
            columns.Add(new KeyValuePair<string, string>("avatar", "string"));
            AddColumns(sheet, columns);

            int rowNo = 2;
            foreach (var servant in servants)
            {
                int colNo = 0;
                IRow row = sheet.CreateRow(rowNo++);

                // 对service进行修正
                ServantErrata errata = ErrataTable[servant.Id];
                servant.AppMediaId = errata.AppMediaId;
                servant.MainAvatar = errata.Avatar;
                if (errata.Name != null)
                    servant.ChineseName = errata.Name;

                row.CreateCell(colNo++).SetCellValue(servant.Id);
                row.CreateCell(colNo++).SetCellValue(servant.JapaneseName);
                row.CreateCell(colNo++).SetCellValue(servant.ChineseName);
                row.CreateCell(colNo++).SetCellValue(servant.EnglishName);
                row.CreateCell(colNo++).SetCellValue(servant.Class);
                row.CreateCell(colNo++).SetCellValue(servant.Rarity);
                row.CreateCell(colNo++).SetCellValue(servant.Cost);
                row.CreateCell(colNo++).SetCellValue(servant.BusterCardAmount);
                row.CreateCell(colNo++).SetCellValue(servant.ArtsCardAmount);
                row.CreateCell(colNo++).SetCellValue(servant.QuickCardAmount);
                row.CreateCell(colNo++).SetCellValue(servant.BusterHits);
                row.CreateCell(colNo++).SetCellValue(servant.ArtsHits);
                row.CreateCell(colNo++).SetCellValue(servant.QuickHits);
                row.CreateCell(colNo++).SetCellValue(servant.ExHits);
                row.CreateCell(colNo++).SetCellValue(servant.NpChargeAtk);
                row.CreateCell(colNo++).SetCellValue(servant.NpChargeDef);
                row.CreateCell(colNo++).SetCellValue(servant.DeathRate);
                row.CreateCell(colNo++).SetCellValue(servant.StarAbsorption);
                row.CreateCell(colNo++).SetCellValue(servant.StarGeneration);
                row.CreateCell(colNo++).SetCellValue(servant.Attribute);
                row.CreateCell(colNo++).SetCellValue(servant.Alignments);
                row.CreateCell(colNo++).SetCellValue(servant.Gender);
                row.CreateCell(colNo++).SetCellValue(servant.AppMediaId);
                row.CreateCell(colNo++).SetCellValue(servant.MainAvatar);
            }

            return true;
        }

        public bool ExportSkills()
        {
            return false;
        }

        public bool AddColumns(ISheet sheet, IList<KeyValuePair<string, string>> columns)
        {
            int colNo = 0;
            IRow nameRow = sheet.CreateRow(0);
            IRow typeRow = sheet.CreateRow(1);
            foreach (var column in columns)
            {
                var name = column.Key;
                var type = column.Value;
                nameRow.CreateCell(colNo).SetCellValue(name);
                typeRow.CreateCell(colNo).SetCellValue(type);
                colNo++;
            }
            return true;
        }
    }
}
